home *** CD-ROM | disk | FTP | other *** search
- /*****
- *
- * Troz CGI
- *
- * MyCGIProcess.c
- *
- *
- *
- * by Grant Neufeld
- *
- * Copyright ©1996 by Grant Neufeld
- *
- * http://arpp.carleton.ca/grant/
- * gneufeld@ccs.carleton.ca
- * grant@acm.org
- *
- *****/
-
- #include "MyConfiguration.h"
- #if kCompileWithCGICode
-
- #include <string.h>
- #include <Threads.h>
- #include <QCAPI.h>
-
- #include "globals.h"
-
- #include "CGI.h"
- #include "CustomHandlers.h"
- #include "DebugUtil.h"
- #include "LogUtil.h"
- #include "MemoryUtil.h"
- #include "ProcessUtil.h"
-
-
- #include "otherprocs.h"
-
-
-
- /*** LOCAL CONSTANTS ***/
-
- #define krtTrozType 'troZ'
-
- #define krsTrozHTTPHeader 10101
- #define krsTrozHTMLFirstChunk 10102
- #define krsTrozHTMLSecondChunk 10103
-
- #define krsTrozPinkyHTML 10110
- #define krsTrozQuickCamHTML 10111
-
-
- /*** LOCAL VARIABLES ***/
-
- Handle vTrozHTTPHeader;
- Handle vTrozHTMLFirstChunk;
- Handle vTrozHTMLSecondChunk;
- int vTrozHTTPHeaderSize;
- int vTrozHTMLFirstChunkSize;
- int vTrozHTMLSecondChunkSize;
-
- Handle vTrozPinkyHTML;
- int vTrozPinkyHTMLSize;
-
- Handle vTrozQuickCamHTML;
- int vTrozQuickCamHTMLSize;
-
- UInt16 vTrozRandomRate;
-
- FSSpec vTrozQuickCamFile;
-
-
- /*** LOCAL FUNCTIONS ***/
-
- Boolean TrozShouldWeNarf ( CGIHdl );
- OSErr TrozUseQuickCam ( CGIHdl );
-
-
- /*** CUSTOM CGI FUNCTION ***/
-
- /* This function is where the CGI is actually processed.
- You should replace its contents with your own.
- You need to allocate (*theCGIHdl)->responseData using MemoryNewHandle.
- Put an HTTP header at the beginning of (*theCGIHdl)->responseData.
- Put your data immediately following the last character of the HTTP header.
- (*theCGIHdl)->responseData will be automatically deallocated by the CGI handler.
- You should set (*theCGIHdl)->responseSize to be the size of the responseData,
- including null terminator if you have one. */
- void
- CustomCGIProcess ( CGIHdl theCGIHdl )
- {
- Boolean processEvent;
- Handle returnData;
- // short returnDataSize;
- OSErr theErr;
- // char * theOriginalURL;
- // short theOriginalURLSize;
- // short scriptNameSize;
- // short serverNameSize;
- SInt8 savedHandleState;
- // long returnDataPostion;
- // short extraBytesForHandle;
-
- /* debugging check to ensure that theCGIHdl is not NULL */
- my_assert ( theCGIHdl != NULL,
- "\pCustomCGIProcess: theCGIHdl is NULL" );
-
- //••• need to test to ensure that the needed CGIHdl fields are present
-
- /* Test to see if the event should be processed */
- processEvent = TrozShouldWeNarf ( theCGIHdl );
- if ( processEvent )
- {
- /* the event met the test requirements, so process it */
- if ( Random() % 2 )
- {
- /* at random, use the QuickCam instead */
- theErr = TrozUseQuickCam ( theCGIHdl );
- if ( theErr == noErr )
- {
- returnData = CGINewHandle ( theCGIHdl, vTrozQuickCamHTMLSize + 1, &theErr );
- if ( returnData != NULL )
- {
- savedHandleState = HGetState ( returnData );
- HLock ( returnData );
-
- strcpy ( *returnData, *vTrozQuickCamHTML );
- QCBlockBoundsCheckNow ();
-
- HSetState ( returnData, savedHandleState );
-
- (*theCGIHdl)->responseSize = vTrozQuickCamHTMLSize + 1;
- (*theCGIHdl)->responseData = returnData;
- }
- }
- }
- else
- {
- theErr = 1;
- }
-
- if ( theErr != noErr )
- {
- /* determine the size of the intended url string */
- // savedHandleState = HGetState ( (Handle)theCGIHdl );
- // HLock ( (Handle)theCGIHdl);
- // scriptNameSize = strlen ( (char *)(*theCGIHdl)->script_name );
- // serverNameSize = strlen ( (char *)(*theCGIHdl)->server_name );
- // HSetState ( (Handle)theCGIHdl, savedHandleState );
-
- // returnDataSize = vTrozHTTPHeaderSize + serverNameSize + scriptNameSize +
- // vTrozHTMLFirstChunkSize + scriptNameSize + vTrozHTMLSecondChunkSize;
-
- returnData = CGINewHandle ( theCGIHdl, vTrozPinkyHTMLSize + 1, &theErr );
- // returnData = CGINewHandle ( theCGIHdl, returnDataSize + 1, &theErr );
- if ( returnData != NULL )
- {
- savedHandleState = HGetState ( returnData );
- HLock ( returnData );
-
- strcpy ( *returnData, *vTrozPinkyHTML );
- QCBlockBoundsCheckNow ();
-
- #if 0
- returnDataPostion = nil;
-
- /* write out the http header */
- strcpy ( *returnData, *vTrozHTTPHeader );
- QCBlockBoundsCheckNow ();
- returnDataPostion += vTrozHTTPHeaderSize;
- /* write out the server name */
- strcpy ( *returnData + returnDataPostion, (*theCGIHdl)->server_name );
- QCBlockBoundsCheckNow ();
- returnDataPostion += serverNameSize;
- /* write out the script name */
- strcpy ( *returnData + returnDataPostion, (*theCGIHdl)->script_name );
- QCBlockBoundsCheckNow ();
- returnDataPostion += scriptNameSize;
- /* write out the first html chunk */
- strcpy ( *returnData + returnDataPostion, *vTrozHTMLFirstChunk );
- QCBlockBoundsCheckNow ();
- returnDataPostion += vTrozHTMLFirstChunkSize;
- /* write out the Original URL, in relative form */
- strcpy ( *returnData + returnDataPostion, (*theCGIHdl)->script_name );
- QCBlockBoundsCheckNow ();
- returnDataPostion += scriptNameSize;
- /* write out the second (and last) html chunk */
- strcpy ( *returnData + returnDataPostion, *vTrozHTMLSecondChunk );
- QCBlockBoundsCheckNow ();
- #endif
-
- /* null terminate the text */
- // (*returnData)[returnDataSize] = nil;
- // QCBlockBoundsCheckNow ();
-
- HSetState ( returnData, savedHandleState );
-
- (*theCGIHdl)->responseSize = vTrozPinkyHTMLSize + 1;
- (*theCGIHdl)->responseData = returnData;
-
- /* you should try to make use of giving time,
- especially in for and while loops or where you have to wait for
- some other process to return data or finish a task. */
- // ProcessGiveTime ( nil );
- }
- }
- }
- } /* CustomCGIProcess */
-
-
- /* This is where we determine whether to interrupt the user's access with
- a Pinky troZ! attack */
- Boolean
- TrozShouldWeNarf ( CGIHdl theCGIHdl )
- {
- Boolean weShouldNarf;
- short scriptNameLength;
- long stringDiff;
- SInt16 randomValue;
-
- weShouldNarf = false;
-
- //••• should deal appropriately with absent CGIHdl fields - IE. default to true for them
-
- if ( ((*theCGIHdl)->method == HTTP_get) || ((*theCGIHdl)->method == HTTP_conditionalGet) )
- {
- /* test if action is preprocessor or ACTION */
- // •••
- // if ( • )
- // {
- scriptNameLength = strlen ( (*theCGIHdl)->script_name );
-
- /* test if last charcter of script_name is '/' */
- if ( ((*theCGIHdl)->script_name)[scriptNameLength - 1] == '/' )
- {
- stringDiff = nil;
- }
- else if ( scriptNameLength > 6 )
- {
- /* test if script_name ends in ".html" */
- stringDiff = strcmp ( ".html", (*theCGIHdl)->script_name + scriptNameLength - 5 );
- }
-
- if ( stringDiff == nil )
- {
- /* get a random to choose whether to narf */
- randomValue = Random() % vTrozRandomRate;
- if ( randomValue == nil )
- {
- weShouldNarf = true;
- }
- }
- // }
- }
-
- return weShouldNarf;
- } /* TrozShouldWeNarf */
-
-
- OSErr
- TrozUseQuickCam ( CGIHdl theCGIHdl )
- {
- OSErr theErr;
-
- theErr = SaveJPEGFromQuickCam ( vTrozQuickCamFile, 32 );
-
- return theErr;
- }
-
-
- /* this function will be called after the cgi result has been returned.
- It will contain the same CGIHdl that was used for the CustomCGIProcess.
- This function's prototype is defined in "CGI.h" */
- void
- CustomCGIPostProcess ( CGIHdl theCGIHdl )
- {
- } /* CustomCGIPostProcess */
-
-
- /*** CUSTOM CGI INITIALIZATION ***/
- #pragma segment Startup
-
- /* Put any of the initialization you need done, here.
- This function will be called once: in-between the startup
- sequence and the main event loop.
- Return true if the initialization was successful, otherwise false.
- An initialization failure will result in the application quitting. */
- Boolean
- CustomCGIStartup ( void )
- {
- OSErr theErr;
- SInt8 savedHandleState;
- Str255 theFileName;
-
- /* get the FSSpec for the file to store the JPEG quickcam grab in */
- GetIndString ( theFileName, 10001, 3 );
- theErr = FSMakeFSSpec ( gProcessFSSpec.vRefNum, gProcessFSSpec.parID, theFileName, &vTrozQuickCamFile );
-
- /* Load in the default blocks of text to return */
-
- /* the pinky html */
- vTrozPinkyHTML = Get1Resource ( krtTrozType, krsTrozPinkyHTML );
- if ( vTrozPinkyHTML == NULL )
- {
- return false;
- }
- savedHandleState = HGetState ( vTrozPinkyHTML );
- HLock ( vTrozPinkyHTML );
- vTrozPinkyHTMLSize = strlen ( (char *)(*vTrozPinkyHTML) );
- HSetState ( vTrozPinkyHTML, savedHandleState );
-
- /* the QuickCam html */
- vTrozQuickCamHTML = Get1Resource ( krtTrozType, krsTrozQuickCamHTML );
- if ( vTrozQuickCamHTML == NULL )
- {
- return false;
- }
- savedHandleState = HGetState ( vTrozQuickCamHTML );
- HLock ( vTrozQuickCamHTML );
- vTrozQuickCamHTMLSize = strlen ( (char *)(*vTrozQuickCamHTML) );
- HSetState ( vTrozQuickCamHTML, savedHandleState );
-
- /* the HTTP Header */
- vTrozHTTPHeader = Get1Resource ( krtTrozType, krsTrozHTTPHeader );
- if ( vTrozHTTPHeader == NULL )
- {
- return false;
- }
- savedHandleState = HGetState ( vTrozHTTPHeader );
- HLock ( vTrozHTTPHeader );
- vTrozHTTPHeaderSize = strlen ( (char *)(*vTrozHTTPHeader) );
- HSetState ( vTrozHTTPHeader, savedHandleState );
-
- /* the first HTML chunk */
- vTrozHTMLFirstChunk = Get1Resource ( krtTrozType, krsTrozHTMLFirstChunk );
- if ( vTrozHTMLFirstChunk == NULL )
- {
- return false;
- }
- savedHandleState = HGetState ( vTrozHTMLFirstChunk );
- HLock ( vTrozHTMLFirstChunk );
- vTrozHTMLFirstChunkSize = strlen ( (char *)(*vTrozHTMLFirstChunk) );
- HSetState ( vTrozHTMLFirstChunk, savedHandleState );
-
- /* the second HTML chunk */
- vTrozHTMLSecondChunk = Get1Resource ( krtTrozType, krsTrozHTMLSecondChunk );
- if ( vTrozHTMLSecondChunk == NULL )
- {
- return false;
- }
- savedHandleState = HGetState ( vTrozHTMLSecondChunk );
- HLock ( vTrozHTMLSecondChunk );
- vTrozHTMLSecondChunkSize = strlen ( (char *)(*vTrozHTMLSecondChunk) );
- HSetState ( vTrozHTMLSecondChunk, savedHandleState );
-
- vTrozRandomRate = 3;
- GetDateTime ( (unsigned long *)(&(qd.randSeed)) );
-
- return true;
- } /* CustomCGIStartup */
-
-
- /*** CUSTOM CGI CLEAN UP ***/
- #pragma segment Main
-
- /* This function is called at quitting time. Put any cleanup you need to do in it.
- Return true if you are succeful.
- Return false if you are unable to quit for some reason (this generally only
- applies when the user cancels)
- allowUserInteract specifies whether you can make user interface calls.
- However, CGIs generally should not rely on any user interface calls, so don't
- depend on them. */
- Boolean
- CustomCGIQuit ( Boolean allowUserInteract )
- {
- #pragma unused (allowUserInteract)
- return true;
- }/* CustomCGIQuit */
-
-
- /*** WSAPI SUPPORT ***/
- #if kCompilingForWSAPI
-
- #define kFileCreatorTypeAny '* '
-
- /* See the WSAPI documentation for further details on the use of
- WSAPI_RegisterAction and WSAPI_RegisterSuffix. */
- WSAPI_ErrorCode
- CustomCGIWSAPIRegister ( WSAPI_CommandPBPtr commandPtr )
- {
- WSAPI_ErrorCode theErr;
-
- /* return plug-in name and abilities, register actions and suffixes. */
-
- /* your code must make at least one of the following WSAPI Register
- calls or there's no way for WebSTAR to pass CGI requests to your plug-in */
-
- /* in this example, we're registering "GRANTSCGI" as an action.
- You should always use the kMyCGIName constant (don't forget to properly
- set it in "MyConfiguration.h". */
- theErr = WSAPI_RegisterAction ( commandPtr, "TROZCGI", kMyCGIName );
- if ( theErr != WSAPI_I_NoErr )
- {
- /* PlugIn Action didn't register. Notify user.
- May want to take some action other than just
- displaying this message */
- WSAPI_DisplayMessage ( commandPtr, "TROZCGI: Couldn't register the action." );
- }
-
- /* in this example, we're registering ".TROZC" as a suffix mapping for
- the "GRANTSCGI" action (registered above). We're also registering it
- for files that have the TEXT filetype and CGI? as their creator type.
- If you don't care about particular file or creator types, then just
- use '* ' (defined as kFileCreatorTypeAny directly above this function). */
- theErr = WSAPI_RegisterSuffix ( commandPtr, "TROZCGI", ".TROZ",
- 'TEXT', 'troZ', "text/html") );
- if ( theErr != WSAPI_I_NoErr )
- {
- /* PlugIn Suffix didn't register. Notify user.
- May want to take some action other than just
- displaying this message */
- WSAPI_DisplayMessage ( commandPtr, "TROZCGI: Couldn't register the suffix." );
- }
-
- return theErr;
- } /* CustomCGIWSAPIRegister */
-
-
- #endif /* kCompilingForWSAPI */
-
-
- #endif /* kCompileWithCGICode */
-
- /*** EOF ***/
-